﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using Slippor.Common.PluginFramework;
using Slippor.Douban.Radio.Assist;
using Slippor.Douban.Radio.Filter;
using Slippor.Douban.Radio.Handler;
using Slippor.Douban.Radio.Search;
using Slippor.Douban.Radio.Share;
using Slippor.Douban.Radio.Tracker;

namespace Slippor.Douban.Radio.BaseForm
{
    public partial class DoubanForm : IApplication
    {
        private readonly List<ISearch> _searchEngines = new List<ISearch>
                                                            {
                                                                new BaiduSearch(),
                                                                new DoubanSearch(),
                                                                new SougouSearch(),
                                                                new KuwoSearch()
                                                            };

        private readonly ServiceContainer _serviceContainer = new ServiceContainer();
        private IFilterService _filterService;
        private IHandlerService _handlerService;
        private PluginService _pluginService;
        private ISearchService _searchService;
        private ITrackerService _trackerService;
        private IShareService _shareService;
        private IHotkeyService _hotKeyService;

        #region IApplication Members

        public Form ActiveMdiChildForm
        {
            get { return this; }
        }

        public Panel MainPanel
        {
            get { return panelMain; }
        }

        public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote)
        {
            _serviceContainer.AddService(serviceType, callback, promote);
        }

        public void AddService(Type serviceType, ServiceCreatorCallback callback)
        {
            _serviceContainer.AddService(serviceType, callback);
        }

        public void AddService(Type serviceType, object serviceInstance, bool promote)
        {
            _serviceContainer.AddService(serviceType, serviceInstance, promote);
        }

        public void AddService(Type serviceType, object serviceInstance)
        {
            _serviceContainer.AddService(serviceType, serviceInstance);
        }

        public void RemoveService(Type serviceType, bool promote)
        {
            _serviceContainer.RemoveService(serviceType, promote);
        }

        public void RemoveService(Type serviceType)
        {
            _serviceContainer.RemoveService(serviceType);
        }

        public new object GetService(Type serviceType)
        {
            return _serviceContainer.GetService(serviceType);
        }

        public void Execute(int command)
        {
            ExcuteCommand(CommandFactory.GetCommand((Command)command, _currentType));
        }
        #endregion

        protected virtual void InitialServices()
        {
            _pluginService = new PluginService(this);
            _searchService = new DoubanRadioSearchService(toolStripMenuItemSearch);
            _filterService = new DoubanRadioFilterService(_filters);
            _trackerService = new DoubanRadioTrackerService();
            _handlerService = new DoubanRadioHandlerService();
            _shareService = new DoubanRadioShareSevice(ShareToolStripMenuItem);
            _hotKeyService = new DoubanRadioHotkeyService(Handle);

            _serviceContainer.AddService(typeof (IPluginService), _pluginService);
            _serviceContainer.AddService(typeof (ISearchService), _searchService);
            _serviceContainer.AddService(typeof (IFilterService), _filterService);
            _serviceContainer.AddService(typeof (ITrackerService), _trackerService);
            _serviceContainer.AddService(typeof (IHandlerService), _handlerService);
            _serviceContainer.AddService(typeof(IShareService), _shareService);
            _serviceContainer.AddService(typeof(IHotkeyService), _hotKeyService);

            foreach (ISearch search in _searchEngines)
            {
                _searchService.AddSearch(search);
            }
            _pluginService.LoadAllPlugin();
            InitialPluginsMenuItem();
        }

        #region IApplication Members
        public void AddToolStripItem(ToolStripItem item)
        {
            menuStripTop.Items.Add(item);
        }

        public void RemoveToolStripItem(ToolStripItem item)
        {
            menuStripTop.Items.Remove(item);
        }
        #endregion

        private PluginManager _pluginManager;
        private void InitialPluginsMenuItem()
        {
            using (var pluginWorker = new BackgroundWorker())
            {
                pluginWorker.DoWork += (sender, e) => SetMenuPlugins();
                pluginWorker.RunWorkerCompleted += (sender, e) =>
                    {
                        var plugins = new Dictionary<PluginCategory, List<ToolStripPluginItem>>();
                        foreach (PluginInfo pInfo in _pluginManager.PluginInfos)
                        {
                            var lvi = new ToolStripPluginItem(pInfo, _pluginManager);
                            if (!plugins.ContainsKey(pInfo.Category))
                            {
                                plugins[pInfo.Category] = new List<ToolStripPluginItem>();
                            }
                            plugins[pInfo.Category].Add(lvi);
                        }
                        foreach (List<ToolStripPluginItem> pluginItems in plugins.Values)
                        {
                            foreach (ToolStripPluginItem item in pluginItems)
                            {
                                toolStripMenuItemPlugins.DropDownItems.Add(item);
                            }
                            toolStripMenuItemPlugins.DropDownItems.Add(new ToolStripSeparator { Width = 30 });
                        }
                        var link = new LinkLabel { Text = StringResource.D_linkLabelPlugin, TextAlign = ContentAlignment.MiddleLeft };
                        var pluginItem = new ToolStripControlHost(link) { BackColor = Color.Transparent, Height = 20 ,Width = 30};
                        link.LinkClicked += (pSender, pE) => RadioUtility.Browse("http://slippor.blogbus.com/logs/62940673.html?s=moreplugin");
                        toolStripMenuItemPlugins.DropDownItems.Add(pluginItem);
                        toolStripMenuItemPlugins.DropDownItems.Add(new ToolStripSeparator { Width = 30 });
                    };
                pluginWorker.RunWorkerAsync();
            }
        }

        private void SetMenuPlugins()
        {
            _pluginManager = new PluginManager(this)
            {
                PluginPath = StaticResources.PluginPath
            };
            _pluginManager.InitialPlugins();
        }
    }
}